package com.jy.app.lib.utils;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by user on 2017/8/10.
 */

public class FindViewBindText {
    private String jsonStringName = "androidJsonObject";
    private DateTimeUtils.EnumDateFmt enumFmt = DateTimeUtils.EnumDateFmt.yyyyMMddHHmm;
    private String fieldPrefix = "tv_";

    /**
     * @param name json原始数据字段名称
     * @return this
     */
    public FindViewBindText jsonStringName(String name){
        jsonStringName = name;
        return this;
    }

    /**
     * @param enumFmt 绑定的时间格式
     * @return
     */
    public FindViewBindText timeFormaat(DateTimeUtils.EnumDateFmt enumFmt){
        this.enumFmt = enumFmt;
        return this;
    }

    /**
     * @param prefix id命名前缀
     * @return
     */
    public FindViewBindText fieldPrefix (String prefix){
        fieldPrefix = prefix;
        return this;
    }

    /**
     * 通过反射绑定界面数据
     * @param activity activity界面自动获取view
     * @param datas 需要绑定的数据 可传多个
     */
    public void viewFindText(Activity activity, Object... datas){
        viewFindText(activity.getWindow().getDecorView(),datas);
    }

    /**
     * 通过反射绑定界面数据
     * @param view 需要绑定值得view
     * @param datas
     */
    public void viewFindText(View view,Object... datas){
        if (datas == null || datas.length<=0) return;
        List<TextView> textViews = getViewText(view);
        for (Object data:datas){
            Set<Field> fields = getFields(data.getClass());
            bindText(view.getContext(),textViews,fields,data);
        }
    }

    /**
     * 获取view中所有的textview
     * */
    private List<TextView> getViewText(View view){
        List<TextView> allchildren = new ArrayList<TextView>();
        if (view instanceof ViewGroup) {
            ViewGroup vp = (ViewGroup) view;
            for (int i = 0; i < vp.getChildCount(); i++) {
                View viewchild = vp.getChildAt(i);
                if (viewchild instanceof TextView)
                allchildren.add((TextView) viewchild);
                //再次 调用本身（递归）
                allchildren.addAll(getViewText(viewchild));
            }
        }
        return allchildren;
    }

    /**
     * 获取数据的所有字段
     * */
    private Set<Field> getFields(Class<?> c){
        Set<Field> data = new HashSet<>();
        String result = c.getSimpleName( ) + ":";
        // 获取类中的公开定义字段(可获得父类字段)
        Field[ ] fields = c.getFields();
        // 循环遍历字段，获取字段对应的属性值
        for ( Field field : fields ) {
            // 如果不为空，设置可见性，然后返回
            field.setAccessible( true );
            data.add(field);
        }
        //获取所字段(不可获取父类方法)
        Field[ ] fields1 = c.getDeclaredFields();
        for ( Field field : fields1 ) {
            // 如果不为空，设置可见性，然后返回
            field.setAccessible( true );
            data.add(field);
        }
        return data;
    }

    private void bindText(Context context,List<TextView> textViews,Set<Field> fields,Object data){
        Resources resources = context.getResources();
        for (TextView textView: textViews){
            try{
                String idName = resources.getResourceEntryName(textView.getId()).replace(fieldPrefix,"");
                boolean isEntityFind = false;
                for (Field field:fields){
                    if (TextUtils.equals(field.getName(),idName)){
                        isEntityFind = true;
                        Object value =getFieldMethod(data,field.getName());
                        if (value==null)
                        value =field.get(data);
                        if (value!=null)
                        textView.setText(String.valueOf(value));
                        findTimeDate(idName,String.valueOf(value),textView);
                    }
                }
                if (!isEntityFind) findJsonFindData(fields,textView,idName,data);
            }catch (Exception e){
                Log.i("ac3",e.toString());
            }
        }
    }

    /**
     * 通过jsonObject自动给textview绑定数据
     * */
    private void findJsonFindData(Set<Field> fields,TextView textView,String idName,Object data) throws Exception {
            for (Field field:fields ){
                if (TextUtils.equals(field.getName(),jsonStringName)){
                    JSONObject jsonObject = new JSONObject((String) field.get(data));
                    String value = jsonObject.getString(idName);
                    textView.setText(value);
                    findTimeDate(idName,value,textView);
                    return;
                }
            }
    }

    /**
     * 当包含time或date时转为北京时间绑定
     * */
    private void findTimeDate(String idName,String value,TextView textView)throws Exception{
        if (idName.contains("time")||idName.contains("date")||idName.contains("Date")||idName.contains("Time")){
            Long time = Long.parseLong(value);
            if ((time>946659661L&&time<2840115661L)||(time>94665966100L&&time<2840115661000L)){  //时间区间在2000年-2060年之间
                String date = DateTimeUtils.dateToString(new Date(time),enumFmt);
                textView.setText(date);
            }
        }
    }

    private Object getFieldMethod(Object data,String name){
        try {
            Class clz =  Class.forName(data.getClass().getName());
            Method m = clz.getMethod("get"+name.substring(0, 1).toUpperCase() + name.substring(1));
            return m.invoke(data);
        }catch (Exception e){
        }
        return null;
    }
}
